/*

Production system



2000/03/28

*/



:- set_prolog_flag(unknown, fail).
%:- prolog_flag(unknown, _, fail).


:- op(10, xfy, then).
:- op(100, fx, if).


:- op(1000, xfy, and).
:- op(1100, xfy, or).


and(X, Y):-
	call(X), call(Y).

or(X, Y):-
	call(X); call(Y).




% The main difference, when compared with previous versions, is the conflict set.



% Inference engine

psys :-

	repeat,

		conflict_set(Set),

		process_conflict_set(Set), !.



process_conflict_set([]):- !.

process_conflict_set(Set):-

	select_action(Set, Action),

	perform_action(Action),

	!,

	fail.



conflict_set(Set):-

	findall(rule(Cond, Act), (rule(Cond, Act), satisfied(Cond)), Set).



% simple minded conflict resolution strategy

select_action([rule(_, Act)|_], Act).





% simple, but maybe sufficient, condition evaluator

satisfied(Cond):- call(Cond).





% simple, but maybe sufficient, action executer

perform_action(Action):- call(Action).



rule(A, B):- if A then B.



/*

% Knowledge base: the villain and the good guy

:- dynamic([hero/1, villain/1, position/2]).


if (hero(H), villain(V), position(H, Ph), position(V, Pv), north_of(Ph, Pv)) then move_south.



if (hero(H), villain(V), position(H, Ph), position(V, Pv), south_of(Ph, Pv)) then move_north.



if (hero(H), villain(V), position(H, Ph), position(V, Pv), east_of(Ph, Pv)) then move_west.



if (hero(H), villain(V), position(H, Ph), position(V, Pv), west_of(Ph, Pv)) then move_east.



if (hero(H), villain(V), position(H, P), position(V, P)) then kill_villain.







% Initial state

hero(james).

villain(jaws).

position(james, (0, 0)).

position(jaws, (3, 4)).



% Predicates

north_of((_, Y1), (_, Y2)):- Y1 > Y2.



south_of((_, Y1), (_, Y2)):- Y1 < Y2.



east_of((X1, _), (X2, _)):- X1 > X2.



west_of((X1, _), (X2, _)):- X1 < X2.





% Actions



kill_villain:-

	write('Hasta la vista, friend!'), nl,

	remove_hero,

	remove_villain.



move_south:-

	write(move_south), nl,

	hero(H),

	retract(position(H, (X, Y))),

	Y1 is Y - 1,

	assert(position(H, (X, Y1))),!.



move_north:-

	write(move_north), nl,

	hero(H),

	retract(position(H, (X, Y))),

	Y1 is Y + 1,

	assert(position(H, (X, Y1))), !.



move_west:-

	write(more_west), nl,

	hero(H),

	retract(position(H, (X, Y))),

	X1 is X - 1,

	assert(position(H, (X1, Y))), !.



move_east:-

	write(move_east), nl,

	hero(H),

	retract(position(H, (X, Y))),

	X1 is X + 1,

	assert(position(H, (X1, Y))), !.



remove_hero:- hero(H), retract(position(H, P)), !.



remove_villain:- villain(V), retract(position(V, P)), !.

*/


